package view.role
{
	import control.manager.LayerManager;
	import control.manager.MapManager;
	import control.manager.RoleManager;
	import control.manager.TaskManager;
	import control.util.astar.NodeGrid;
	
	import data.GameConst;
	import data.MapData;
	import data.PlayerData;
	import data.RoleVO;
	
	import flash.display.Bitmap;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import view.item.ExitsView;
	import view.item.PathTrack;
	import view.layer.GameLayer;
	import view.layer.MapLayer;
	import view.ui.UIMain;
	import view.ui.UIPopupLayer;
	import view.ui.UITaskTalk;
	import view.ui.minimap.MiniMapContainer;
	import view.ui.minimap.UIMiniMap;

	public class MapPlayer extends MapObject
	{
		public static const START_ATT :String = "START_ATT";
		public static const STOP_ATT :String = "STOP_ATT";
		public static const SHOW_TALK :String = "SHOW_TALK";
		public static const HIDE_TALK :String = "HIDE_TALK";
		public static const NORMAL :String = "NORMAL";
		public static const MOVE :String = "MOVE";
		
		
		/**
		 * 移动速度 
		 */		
		public var speed :Number;
		/**
		 *  XY轴上的合力
		 */		
		public var forceSpeed :Point;
		/**
		 * 是否在移动 
		 */		
		public var isWalking :Boolean = false;
		/**
		 * 是否已经走到终点 
		 */		
		public var isWalk2End :Boolean = false;
		/**
		 * 层场景移动速度 
		 */		
		public var sceneMoveSpeed :Number;
		/**
		 * 玩家行走路径 
		 */		
		public var path :Array;
		/**
		 * 玩家角色数据 
		 */		
		public var playerData :PlayerData;
		/**
		 *  行走数组的索引值 
		 */		
		private var index :int = 0;
		/**
		 * 当前地图的信息 
		 */		
		private var mapData :MapData;
		/**
		 * 引用游戏层 
		 */		
		private var _gameLayer :GameLayer;
		
		

		public function MapPlayer(roleData :PlayerData)
		{
			super(roleData);
			this.mouseChildren = this.mouseEnabled = false;
			this.playerData = roleData;
			this.speed = roleData.playerSpeed;
			
		}
		
		/**
		 * 人物寻路 
		 * @param startPoint 像素坐标
		 * @param endPoint 像素坐标
		 * 
		 */		
		public function findPath(startPoint :Point, endPoint:Point):void
		{
			this.mapData = MapManager.instance.curMapData;
			var mapLayer :MapLayer = LayerManager.instance.getLayer(MapLayer.NAME) as MapLayer;
			
			var w :int = mapData.mapWalkGapWidth;
			var h :int = mapData.mapWalkGapHeight;
			var sp :Point = MapManager.instance.getCellPoint(w,h,startPoint.x,startPoint.y);
			
			var ep :Point = MapManager.instance.getCellPoint(w,h,endPoint.x,endPoint.y);
			
			//if(mapData.mapWalkAry[ep.y][ep.x]) return;
			var nodeGrid :NodeGrid = MapManager.instance.nodeGrid;
			if(nodeGrid)
			{
				if(!nodeGrid.getNode(ep.x,ep.y).walkable) 
				{
					return;
				}
			}
			this.path  = MapManager.instance.findPath(sp,ep);
//			trace(path);
			RoleManager.instance.player.curClickObj = null;
			if(this.path)
			{
				miniMapContainer.drawPath(this.path);
				PathTrack.I.show();
				this.isWalking = true;
				this.isWalk2End = false;
				this.index = 1;
			}
			
		}
		/**
		 * 显示对话 
		 * 
		 */		
		public function showTalk():void
		{
			trace("显示对话框");
			this.curStatus = MapPlayer.SHOW_TALK;
			var ui :UITaskTalk
			if(TaskManager.instance.isFirstGame2Task())
			{
				ui = new UITaskTalk(this.curClickObj as MapNPC,true);
			}else
			{
				ui = new UITaskTalk(this.curClickObj as MapNPC);
			}
			UIPopupLayer.I.show(ui);
		}
		/**
		 * 隐藏对话 
		 * 
		 */		
		public function hideTalk():void
		{
			
			if(UIPopupLayer.I.isShow)
			{
				
				trace("关闭对话框");
				this.curStatus = MapPlayer.HIDE_TALK;
				UIPopupLayer.I.hide();
				this.curClickObj = null;
			}
		}
		/**
		 * 攻击怪物 
		 * 
		 */		
		public function attMonster():void
		{
			trace("攻击怪物");
			this.curStatus = MapPlayer.START_ATT;
			
			//调整攻击怪物时的方向
			var end :MapMonster = this.curClickObj as MapMonster;
			var endPoint :Point = end.attPosition;
			var targetX :Number = endPoint.x - this.x;
			var targetY :Number = endPoint.y - this.y;
			var angle :Number = Math.atan2(targetY,targetX);
			setDirection(angle);
			this.animationObj.playAction(this.curAction,this.curDirection);
		}
		/**
		 * 发出攻击波的起点 
		 * @return 
		 * 
		 */		
		public function attStartPoint():Point
		{
			return new Point(this.x - 10,this.y - 60);
		}
		/**
		 * 停止攻击 
		 */		
		public function stopAtt():void
		{
			this.curStatus = MapPlayer.STOP_ATT;
		}
		
		override public function update():void
		{
			super.update();
			walk();
		}
		
		override public function onClick(e:* = null):void
		{
			super.onClick(e);
		}
		/**
		 * 人物行走 
		 * 
		 */		
		private function walk():void
		{
			if(!this.isWalking) return;
			if(this.path && this.path.length > 0)
			{
				this.curStatus = MOVE;
				//行走到终点
				if(this.index > this.path.length - 1)
				{
					walkEnd();
					return;
				}
				//取出路径点
				var p :Point =  this.path[this.index];
				var walkW :int = this.mapData.mapWalkGapWidth;
				var walkH :int = this.mapData.mapWalkGapHeight;
				//求目标在地图上的实际坐标
				var tx :Point = MapManager.instance.getPixelPoint(walkW,walkH,p.x,p.y);
				var targetX:Number = tx.x;
				var targetY:Number = tx.y;
				var distX:Number = targetX - this.x;
				var distY:Number = targetY - this.y;
				forceSpeed  = new Point();
				
				var angle:Number = Math.atan2(distY, distX);
				forceSpeed.x = speed * Math.cos(angle);
				forceSpeed.y = speed * Math.sin(angle);
				
				//如果总路径小于总速度则表示已经抵达目的地，返回进行下一点行走
				if( Math.sqrt(distX * distX + distY * distY) < 5 )
				{
					this.x = targetX;
					this.y = targetY;
					this.index++;
					return;
				}
				else
				{
					//如果还没抵达目的点，则继续行走
					this.x += forceSpeed.x;
					this.y += forceSpeed.y;
					//设置透明，模拟人站在树下或建筑物里
					setRoleVisible();
					//确定行走方向
					setDirection(angle);
					this.curAction = RoleVO.WALK;
					if(this.curAction != this.animationObj.curRoleAction || this.curDirection != this.animationObj.curRoleDirection)
					{	
						this.animationObj.playAction(this.curAction,this.curDirection);
					}
					//检查是否是过传送点
					if(checkIsHitExits() == false)
					{
						//检查是否需要加载地图块
						gameLayer.mapLayer.checkAndLoadMapTileItem();
//						gameLayer.mapLayer.checkAndRemoveMapTileItem();
					}
					
					//如果有当前目标是NPC则对话，如果是怪物则攻击
					if(this.curClickObj && this.curStatus == MapPlayer.MOVE)
					{
						var startPoint :Point = this.position;
						var endPoint :Point = this.curClickObj.position;
						if(Point.distance(startPoint,endPoint) < this.playerData.playerATTRange)
						{
							for(var i :int = this.path.length - 1; i >= 0; i--)
							{
								this.path.splice(i,1);
							}
							this.path = null;
							walkEnd();
							//碰到npc对话
							if(this.curClickObj is MapNPC)
							{
								showTalk();
							}else if(this.curClickObj is MapMonster)  //碰到怪物攻击
							{
								attMonster();
							}
							return;
						}else
						{
//							hideTalk();
						}
					}
					
				}
				//地图移动
				Layermove();
			}
			
		}
		
		/**
		 * 正常行走结束
		 */		
		private function walkEnd():void
		{
			this.isWalking = false;
			this.isWalk2End = true;
			this.curAction = RoleVO.WAIT;
			this.animationObj.playAction(this.curAction,this.curDirection);
			//清空路径层
			miniMapContainer.clearPath();
			PathTrack.I.hide();
		}
		/**
		 * 是否与出口碰撞 
		 * @return 
		 * 
		 */		
		private function checkIsHitExits():Boolean
		{
			var exitsViewList :Vector.<ExitsView> = gameLayer.mapLayer.exitsViewList;
			var result :Boolean = false;
			for each(var exitsView :ExitsView in exitsViewList)
			{
				if(this.hitTestObject(exitsView))
				{
					this.isWalking = false;
					this.path = null;
					miniMapContainer.clearPath();
					this.animationObj.playAction(RoleVO.WAIT,RoleVO.DOWN);
					trace("xx平原");
					
					var mapID :int = exitsView.getExitsData().nextMapID;
					var mapData :MapData = MapManager.instance.findByID(mapID);
					var visibleW :int = stage.stageWidth;
					var visibleH :int = stage.stageHeight;
					gameLayer.mapLayer.changeMap(mapData,visibleW,visibleH);
					setPlayerPosition(exitsView.getExitsData().nextMapBornPoint);
					gameLayer.lockAt(this.x,this.y);
					result = true;
					PathTrack.I.hide();
					UIPopupLayer.I.showLoading();
					break;
				}
			}
			return result;
		}
		
		private function setPlayerPosition(p :Point):void
		{
			var w :int = this.mapData.mapWalkGapWidth;
			var h :int = this.mapData.mapWalkGapHeight;
			var tp :Point = MapManager.instance.getPixelPoint(w,h,p.x,p.y);
			this.x = tp.x;
			this.y = tp.y;
		}
		/**
		 * 设置角色的透明度 
		 * 
		 */		
		private function setRoleVisible():void
		{
			var w :int = this.mapData.mapWalkGapWidth;
			var h :int = this.mapData.mapWalkGapHeight;
			var visbleAry :Array = this.mapData.mapVisbleAry;
			var indexP :Point = MapManager.instance.getCellPoint(w,h,this.x,this.y);
			if(!visbleAry[indexP.y][indexP.x])
			{
				this.alpha = .5;
			}else
			{
				this.alpha = 1;
			}
		}
		/**
		 * 图层移动 
		 * 
		 */		
		private function Layermove():void
		{
			var mapW :int = this.mapData.mapWidth;
			var mapH :int = this.mapData.mapHeight;
			var visibleW :int = stage.stageWidth;
			var visibleH :int = stage.stageHeight;
			//左右上下的图层移动范围
			
			var p :Point = this.gameLayer.localToGlobal(new Point(this.x,this.y));
//			var leftSide :Boolean = this.x >= visibleW/2;
//			var rightSide :Boolean = this.x <= (mapW - visibleW/2);
//			var topSide :Boolean = this.y >= visibleH/2;
//			var bottomSide :Boolean = this.y <= (mapH - visibleH/2);
			
			var leftSide :Boolean = this.x < visibleW/2;
			var rightSide :Boolean = this.x > (mapW - visibleW/2);
			var topSide :Boolean = this.y < visibleH/2;
			var bottomSide :Boolean = this.y > (mapH - visibleH/2);
			
			var speedX :Number = 0;
			var speedY :Number = 0;
			//X方向
			if(!leftSide && !rightSide)
			{
				speedX = -this.forceSpeed.x;
			}
			//Y方向
			if(!topSide && !bottomSide)
			{
				speedY = -this.forceSpeed.y;
			}
			//游戏层移动
			gameLayer.sceneMoveSpeed = new Point(speedX,speedY);
			gameLayer.updatePosition();
			
//			gameLayer.lockAt(this.x,this.y);
			
			miniMapContainer.lockAt(this.x/GameConst.MAP_SCALE,this.y/GameConst.MAP_SCALE);
			
			if(miniMapUI)
			{
				miniMapUI.sceneXYTxt.text = int(this.x) + "." + int(this.y);
			}
		}
		
		/**
		 * 取得行走方向，水平向右为0，顺时针旋转
		 * (注意：在tile的宽=2*高时，右下 左下 左上 右上并非是45度)
		 * 0 -- 右		0度
		 * 1 -- 右下		45度
		 * 2 -- 下		90度
		 * 3 -- 左下		135度
		 * 4 -- 左		180度
		 * 5 -- 左上		-135度
		 * 6 -- 上		-90度
		 * 7 -- 右上		-45度
		 */
		private function setDirection(radians:Number):void
		{
			/**
			 角度(degrees)和弧度(radians)之间的转换关系式是：
			 radians = (Math.PI / 180) * degrees
			 **/
			var degrees:Number = radians * 180 / Math.PI;	//角度
			
			//八方向 360/8=45，左上角为元点，右向为横轴，逆时针角度为负，顺时针为正  
			// 也可用弧度直接算
			this.curDirection = Math.round( degrees / 45 );	
			
			if (degrees < 0)	//角度为负
			{
				this.curDirection = Math.abs(this.curDirection + 8);
			}
			
			//转成跟图片一致的
			switch (this.curDirection)
			{
				case 0:
					this.curDirection = RoleVO.RIGHT;
					break;
				case 1:
					this.curDirection = RoleVO.DOWNRIGHT;
					break;
				case 2:
					this.curDirection = RoleVO.DOWN;
					break;
				case 3:
					this.curDirection = RoleVO.DOWNLEFT;
					break;
				case 4:
					this.curDirection = RoleVO.LEFT;
					break;
				case 5:
					this.curDirection = RoleVO.UPLEFT;
					break;
				case 6:
					this.curDirection = RoleVO.UP;
					break;
				case 7:
					this.curDirection = RoleVO.UPRIGHT;
					break;
			}
		}
		
		
		
		/**
		 * 获取人物角色对游戏层的引用  
		 * @return 
		 * 
		 */		
		public function get gameLayer():GameLayer
		{
			return _gameLayer;
		}
		
		public function get miniMapContainer():MiniMapContainer
		{
			var mainUI :UIMain = LayerManager.instance.getLayer(UIMain.NAME) as UIMain;
			return mainUI.miniMapContainer;
		}
		
		public function get miniMapUI():UIMiniMap
		{
			var mainUI :UIMain = LayerManager.instance.getLayer(UIMain.NAME) as UIMain;
			return mainUI.miniMapUI;
		}
		/**
		 * 设置人物角色对游戏层的引用 
		 * @param value
		 * 
		 */		
		public function set gameLayer(value:GameLayer):void
		{
			_gameLayer = value;
		}
	}
}